#include <assert.h>
#include <stdio.h>
#include <imbus.h>

#define NO_TEST_OBJECT_MAIN
#include "test_object.h"
#include "test_object.c"

void for_each_array (IMPointer a, IMPointer u)
{
    IMType type = im_object_get_type (a);

    printf ("%s: ", im_type_get_name (type));

    if (type == IM_TYPE_VALUE) {
        IMValue *v = IM_VALUE (a);
        switch (im_value_get_value_type (v)) {
            case IM_TYPE_CHAR:
                printf ("Char %c\n", im_value_get_char (v));
                break;
            case IM_TYPE_UCHAR:
                printf ("UChar %c\n", im_value_get_uchar (v));
                break;
            case IM_TYPE_INT32:
                printf ("Int32 %d\n", im_value_get_int32 (v));
                break;
            case IM_TYPE_UINT32:
                printf ("UInt32 %u\n", im_value_get_uint32 (v));
                break;
            case IM_TYPE_INT64:
                printf ("Int64 %lld\n", im_value_get_int64 (v));
                break;
            case IM_TYPE_UINT64:
                printf ("UInt64 %llu\n", im_value_get_uint64 (v));
                break;
            case IM_TYPE_DOUBLE:
                printf ("Double %lf\n", im_value_get_double (v));
                break;
            case IM_TYPE_C_STRING:
                printf ("String %s\n", im_value_get_c_string (v));
                break;
            default:
                if (IM_TYPE_IS_OBJECT (im_value_get_value_type (v))) {
                    printf ("Object %s\n", im_type_get_name (im_value_get_value_type (v)));
                }
                break;
        }
    } else if (im_type_is_a (type, TYPE_POINT)) {
        point_draw (a);
    } else {
        printf ("Unknown object\n");
    }
}

void print_object_array (IMObjectArray *a)
{
    printf ("sizeof (%s) = %d, has %d objects\n",
            im_type_get_name (im_object_get_type (a)), 
            im_object_sizeof (a),
            im_object_array_size (a));

    printf ("All objects:\n");

    im_object_array_foreach (a, for_each_array, 0);
}

int main (int argc, char *argv [])
{
    IMObjectArray *a;
    IMValue       *v;
    Point         *p;

    im_init (&argc, &argv);

    a = im_object_array_new ();

    v = im_value_new ();
    im_value_set_char (v, 'A');
    im_object_array_append (a, v);

    v = im_value_new ();
    im_value_set_uchar (v, 'A');
    im_object_array_append (a, v);

    v = im_value_new ();
    im_value_set_int32 (v, -12345);
    im_object_array_insert (a, 1, v);

    v = im_value_new ();
    im_value_set_uint32 (v, 12345);
    im_object_array_append (a, v);

    v = im_value_new ();
    im_value_set_int64 (v, -1234567890123LL);
    im_object_array_prepend (a, v);

    v = im_value_new ();
    im_value_set_uint64 (v, 1234567890123LL);
    im_object_array_append (a, v);

    v = im_value_new ();
    im_value_set_double (v, 1.2345);
    im_object_array_append (a, v);

    v = im_value_new ();
    im_value_set_c_string (v, "Hello world!");
    im_object_array_append (a, v);

    p = point_new (10, 10);
    im_object_array_append (a, p);

    p = (Point *) circle_new (15, 15, 20);
    im_object_array_append (a, p);

    print_object_array (a);

    im_object_unref (a);

    return 0;
}

/*
vi:ts=4:nowrap:ai:expandtab
*/
